package com.smcaiot.filesync.starter.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.smcaiot.filesync.starter.annotation.OriginalPath;
import com.smcaiot.filesync.starter.annotation.SmallPath;
import com.smcaiot.filesync.starter.app.FileSyncProperties;
import com.smcaiot.filesync.starter.handler.impl.AbstractCompressPicHandler;
import com.smcaiot.filesync.starter.handler.impl.AbstractPullFileHandler;
import com.smcaiot.filesync.starter.handler.impl.AbstractPushFileHandler;
import com.smcaiot.filesync.starter.service.FileSyncService;
import com.smcaiot.filesync.starter.util.ReflectTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: cz
 * @Date: 2023/6/28
 * @Description:
 */
@Service
@Slf4j
public class FileSyncServiceImpl implements FileSyncService {

    @Autowired
    private FileSyncProperties fileSyncProp;
    @Autowired
    private Map<String, AbstractCompressPicHandler> compressPicHandlerMap;
    @Autowired
    private Map<String, AbstractPushFileHandler> pushFileHandlerMap;
    @Autowired
    private Map<String, AbstractPullFileHandler> pullFileHandlerMap;

    @Override
    public void compressFiles() {
        compressPicHandlerMap.values().forEach(handler -> {
            List files = handler.findNotCompressList();
            if (CollUtil.isEmpty(files)) {
                return;
            }
            log.debug("待压缩文件数：{}, Handler: {}", files.size(), handler.getClass().getSimpleName());
            List list = new ArrayList();
            files.forEach(file -> compressFile(handler, file, list));
            handler.finish(list);
        });
    }

    private <T> void compressFile(AbstractCompressPicHandler handler, T entity, List list) {
        String filePath = ReflectTool.getFieldValue(entity, OriginalPath.class);
        if (StrUtil.isBlank(filePath)) {
            log.debug("压缩文件时，找不到文件地址");
            return;
        }
        String remotePath = handler.process(filePath);
        ReflectTool.setFieldValue(entity, SmallPath.class, remotePath);
        list.add(entity);
    }

    @Override
    public void push() {
        pushFileHandlerMap.values().forEach(handler -> {
            List entities = handler.findNotSyncList();
            if (CollUtil.isEmpty(entities)) {
                return;
            }
            log.debug("--------------------- 本次任务共计需要推送文件 {} 个 ---------------------", entities.size());
            List list = new ArrayList();
            entities.stream().forEach(entity -> pushFile(handler, entity, list));
            handler.finish(list);
        });
    }

    private <T> void pushFile(AbstractPushFileHandler handler, T entity, List list) {
        boolean sync = handler.syncFile(entity);
        if (sync) {
            list.add(entity);
        }
    }

    @Override
    public void pull() {
        pullFileHandlerMap.values().forEach(handler -> {
            List entities = handler.findNotSyncList();
            if (CollUtil.isEmpty(entities)) {
                return;
            }
            log.debug("--------------------- 本次任务共计需要拉取文件 {} 个 ---------------------", entities.size());
            List list = new ArrayList();
            entities.stream().forEach(entity -> pullFile(handler, entity, list));
            handler.finishPull(list);
        });
    }

    private <T> void pullFile(AbstractPullFileHandler handler, T entity, List list) {
        boolean sync = handler.syncFile(entity);
        if (sync) {
            list.add(entity);
        }
    }

}
